package other.system.client.sap;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.ScheduleJob;
import com.rkhd.platform.sdk.api.annotations.RequestMethod;
import com.rkhd.platform.sdk.api.annotations.RestApi;
import com.rkhd.platform.sdk.api.annotations.RestMapping;
import com.rkhd.platform.sdk.api.annotations.RestQueryParam;
import com.rkhd.platform.sdk.data.model.InvoiceDetail__c;
import com.rkhd.platform.sdk.data.model.Invoice__c;
import com.rkhd.platform.sdk.data.model.SyncConfig__c;
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
import com.rkhd.platform.sdk.exception.ScriptBusinessException;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.param.ScheduleJobParam;
import com.rkhd.platform.sdk.service.FutureTaskService;
import com.rkhd.platform.sdk.service.XoqlService;
import com.rkhd.platform.sdk.task.FutureTask;
import org.apache.commons.lang.StringUtils;
import other.system.client.apitool.SAPClientUtils;
import other.system.client.util.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 同步SAP开票信息
 * @Author 黎炎松
 * 2024-07-30 13:52
 */
@RestApi(baseUrl = "/xsy/sap")
public class SyncSapInvoice implements ScheduleJob, FutureTask {

    private static HCXObjectService hcxObjectService = new HCXObjectService();

    private static XoqlService xoqlService = XoqlService.instance();

    private static final Logger logger = LoggerFactory.getLogger();
    private static final String LOGGER_MSG = "同步SAP开票信息 ==> ";

    /**
     * 计划作业
     * @param scheduleJobParam
     */
    @Override
    public void execute(ScheduleJobParam scheduleJobParam) {
        try {
            logger.info(LOGGER_MSG + "触发计划作业");
            String messageId = FutureTaskService.instance().addFutureTask(getClass(), "");
            logger.info(LOGGER_MSG + "异步ID:" + messageId);
        } catch (Exception e) {
            logger.error(LOGGER_MSG + " ----- 发生异常：" + e.getMessage());
        }
    }


    /**
     * 异步任务
     * @param s
     * @throws ScriptBusinessException
     */
    @Override
    public void execute(String s) throws ScriptBusinessException {
        logger.info(LOGGER_MSG + "执行异步任务");
        syncInvoice("");
    }

    /**
     * 页面手动同步
     * @param invoiceId
     * @return
     */
    @RestMapping(value = "/getSapInvoiceData", method = RequestMethod.POST)
    public String getSapInvoiceData(@RestQueryParam(name = "id") Long invoiceId) throws ApiEntityServiceException {
        logger.info(LOGGER_MSG + "执行了按钮事件 = " + invoiceId);

        String sql = "select id,name from invoiceDetail__c where invoice__c = " + invoiceId;
        List<InvoiceDetail__c> invoiceDetailList = hcxObjectService.query(sql, InvoiceDetail__c.class);
        if (invoiceDetailList == null || invoiceDetailList.size() <= 0) {
            return TfReturnMsgTools.getFailResult("开票明细不可为空");
        }

        String nameStr = invoiceDetailList.stream().map(v -> v.getName()).collect(Collectors.joining(","));
        return syncInvoice(nameStr);
    }


    public static void main(String[] args) throws ApiEntityServiceException {
        //new SyncSapInvoice().syncInvoice("INDE2400329");
        new SyncSapInvoice().syncInvoice("");
    }

    /**
     * 同步sap开票回款信息
     * @param numberStr 明细编号，用于页面手动同步
     */
    public String syncInvoice(String numberStr) {
        try {
            logger.info(LOGGER_MSG + "处理开始 numberStr = " + numberStr);

            // 从数据配置表中获取上次更新时间
            String sql = "select id,lastSyncTime__c from syncConfig__c where syncKey__c = 'SAP_INVOICE_INFO'";
            SyncConfig__c syncConfig = hcxObjectService.queryOne(sql, SyncConfig__c.class);
            logger.info(LOGGER_MSG + "处理开始 syncConfig = " + syncConfig);
            if (syncConfig == null) {
                logger.debug(LOGGER_MSG + "配置信息不存在");
                return TfReturnMsgTools.getFailResult("配置信息不存在");
            }

            // 获取同步时间
            String startDate = syncConfig.getLastSyncTime__c();
            String endDate = HCDateUtils.dateToString(new Date(), "yyyyMMddHHmmss"); // 同步结束时间
            if (StringUtils.isBlank(startDate)) {
                // 如果为空则退回1天前
                startDate = HCDateUtils.getDaysBeforeString(1, "yyyyMMddHHmmss");
            }

            JSONObject params = new JSONObject();
            params.put("I_JKLX", "FH"); // 说明: 入参“JS”则为CRM推数据；入参"FH"则为sap返回数据给CRM。当入参为“FH"，I_NAME必输
            if (StringUtils.isNotBlank(numberStr)) {
                params.put("I_NAME", numberStr); // 根据编号
            } else {
                params.put("I_BTIME", startDate); // 修改开始时间
                params.put("I_ETIME", endDate); // 修改结束时间
            }
            logger.debug(LOGGER_MSG + "params" + params);

            // 获取开票数据信息
            ResultBody resultBody = SAPClientUtils.sendPost(params, SAPClientUtils.INVOICE_URL, "");
            logger.debug(LOGGER_MSG + "resultBody:" + resultBody);
            if (!Objects.equals(resultBody.getCode(), "200")) {
                logger.error(LOGGER_MSG + "获取SAP开票回款数据异常:" + resultBody.getMessage());
                return TfReturnMsgTools.getFailResult("获取SAP开票回款数据异常:" + resultBody.getMessage());
            }

            JSONObject result = (JSONObject) resultBody.getResult();
            List<JSONObject> invoiceList = JSONArray.parseArray(result.getString("IT_KPXXFH"), JSONObject.class);
            logger.info(LOGGER_MSG + "invoiceList: " + invoiceList.size());
            if (invoiceList.size() <= 0) {
                logger.debug(LOGGER_MSG + "暂无需要处理的开票回款数据");
                if (StringUtils.isBlank(numberStr)) {
                    // 更新同步配置
                    syncConfig.setLastSyncTime__c(endDate);
                    syncConfig.setLastSyncCount__c(0L);
                    hcxObjectService.update(syncConfig);
                }
                return TfReturnMsgTools.getFailResult("查询SAP暂无需要处理的开票回款数据");
            }

            // 根据开票ID进行分组（因为是根据整个开票为主体进行开票，返回的开票明细数据中开票数据都是一样的）
            Map<String, List<JSONObject>> invoiceListMap = invoiceList.stream().collect(Collectors.groupingBy(e -> e.getString("INVOICEID__C")));
            logger.info(LOGGER_MSG + "invoiceListMap: " + invoiceListMap.size());

            // 根据开票ID，获取开票的id值
            String invoiceIDs = invoiceListMap.keySet().stream().map(v -> "'" + v + "'").collect(Collectors.joining(","));
            sql = "select id,invoiceID__c from invoice__c where invoiceID__c in (" + invoiceIDs + ")";
            List<JSONObject> crmInvoiceList = xoqlService.query(sql, true).getRecords();
            Map<String, Long> crmInvoiceMap = crmInvoiceList.stream().collect(Collectors.toMap(e -> e.getString("invoiceID__c"), e1 -> e1.getLong("id")));
            logger.debug(LOGGER_MSG + "crmInvoiceMap: " + crmInvoiceMap.size());

            // 获取开票数据进行保存
            List<Invoice__c> upInvoiceList = new ArrayList<>();
            for (String invoiceId : invoiceListMap.keySet()) {
                Invoice__c invoice = new Invoice__c();
                JSONObject invoiceObj = invoiceListMap.get(invoiceId).get(0);

                invoice.setInvoiceNumber__c(invoiceObj.getString("INVOICENUMBER__C")); // 开票号 invoiceNumber__c
                invoice.setTicketLink__c(invoiceObj.getString("TICKETLINK__C")); // 发票链接 ticketLink__c

                // 判断系统中是否存在，存在则更新
                if (crmInvoiceMap.containsKey(invoiceId)) {
                    invoice.setId(crmInvoiceMap.get(invoiceId));
                    upInvoiceList.add(invoice);
                }

                if (upInvoiceList.size() > 50) {
                    Boolean update = hcxObjectService.batchUpdate(upInvoiceList);
                    System.out.println("update = " + update);
                    upInvoiceList.clear();
                }
            }


            // 批量修改
            if (upInvoiceList.size() > 0) {
                logger.debug(LOGGER_MSG + "修改的数据: " + upInvoiceList);
                Boolean update = hcxObjectService.batchUpdate(upInvoiceList);
                if (!update) {
                    logger.debug(LOGGER_MSG + "批量修改异常");
                    return TfReturnMsgTools.getFailResult("批量修改异常");
                }
            }

            // 更新同步配置
            if (StringUtils.isBlank(numberStr)) {
                syncConfig.setLastSyncTime__c(endDate);
                syncConfig.setLastSyncCount__c(Long.valueOf(crmInvoiceMap.size()));
                Boolean update = hcxObjectService.update(syncConfig);
                if (!update) {
                    logger.error(LOGGER_MSG + "更新同步配置异常");
                    return TfReturnMsgTools.getFailResult("更新同步配置异常");
                }
            }

            logger.debug(LOGGER_MSG + "处理成功");
            return TfReturnMsgTools.getSuccessResult("处理成功");
        } catch (Exception e) {
            logger.error(LOGGER_MSG + "保存开票信息异常: " + e.getMessage());
            return TfReturnMsgTools.getFailResult("保存开票信息异常: "  +e.getMessage());
        }
    }


}
